﻿using ExchangeClient.Abstractions;
using ExchangeClient.Abstractions.Model;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using SyncService.Abstractions.Services;
using SyncService.Core.Services;
using System;
using System.Collections.Generic;
using System.Composition;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace SyncService.Core.Jobs
{
    [Export(typeof(ISyncService))]
    [ExportMetadata(YdConstants.ID, "ClearScrapOrder")]
    public class ClearScrapOrderServices : AssetSyncServiceBase
    {
        public ClearScrapOrderServices() : base(YdConstants.YIDEA, "mysqlcache", "")
        {
        }

        protected override void InitializeContext()
        {
            base.InitializeContext();
        }

        public override void ExecuteCore()
        {

            //Thread.Sleep(60000);
            Logger.Info("开始对中间程序数据库的报废资产进行处理.....");
            Console.WriteLine("开始对中间程序数据库的报废资产进行处理.....");
            ;
            try
            {
                #region 等待创建的报废资产
                //查询数据库待创建的报废资产
                string selectsql = ScrapConstants.SelectSqlTemplate;
                JsonObject keyValuePairs = new JsonObject()
                {
                    ["Type"] = "ClearScrapOrderSelect",
                    ["SelectSql"] = selectsql
                };
                JsonObject? query = ToClient.SendNotifications(keyValuePairs);
                #endregion

                if (query["chechklist"]?.GetValue<bool>() == true)
                {

                    //待处理的报废资产数据
                    var dictList = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(query["data"]?.ToString());
                    #region 自定义表单字段获取
                    var VformId1 = UserDefines.First(x => x.Name == "报废自定义表单");
                    var claerReson = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "清理人");
                    var cleatDate = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "清理日期");
                    var staffNo = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "工号");
                    var Name = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "名字");
                    var assetType = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产分类");
                    var department = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "部门选择");
                    var companySelect = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "公司选择");
                    var companyCode = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "公司代码");
                    var yuanZhi = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "原值");
                    var JingZhi = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "净值");
                    var ScrapType = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "报废类型");
                    var Number = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "数字");
                    var ScraplongText = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "清理说明");



                    var AssetList = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表");
                    var BarCode = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产编码");
                    var FinancialAssetCode = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "财务资产编码");
                    //var AssetName = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产名称");
                    //var AreaName = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "区域名称");
                    var JoinName = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "关联数据");
                    var AssetTypeCode = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "类别编码");
                    var TypeCodeIF = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "编码判断");
                    var AssetList_yuanzhi = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.原值");
                    var AssetList_AccumDeper = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.累计折旧");
                    var AssetList_jingzhi = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.净值");
                    var AssetList_Number1 = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.数字1");
                    //var AssetList_AccumDeperIF = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "判断累计折旧是不是为0");
                    var AssetList_CunFangAddress = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.存放地点");
                    var AssetList_CBZX_Code = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.成本中心代码");
                    var AssetList_CBZX_Name = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.成本中心名称");
                    var AssetList_Deperlast = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.减累计折旧");
                    var AssetList_DeperOn = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.加累计折旧");
                    //var AssetList_AssetState = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.资产状态");
                    var AssetList_WTD = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.是否递延");
                    var AssetList_Number2 = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.数字2");
                    var AssetList_WTP = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "资产列表.是否过账");
                    var ProcessIdentifier = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "流程标识");

                    var Asset1_FinancialAssetCode = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "财务资产编码");
                    var Asset1_yuanzhi = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "资产原值");
                    var Asset1_jingzhi = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "资产净值");
                    var Asset1_CFaddress = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "资产净值");
                    var Asset1_CBZXcode = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "成本中心代码");
                    var Asset1_CBZXname = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "成本中心名");
                    var Asset1_WTD = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "是否递延");
                    var Asset1_WTP = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "是否过账");
                    var Asset1_company = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "公司名称");
                    var Asset1_companyCode = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "公司代码");
                    #endregion
                    // 构建参数化的WHERE条件
                    var conditions = new List<string>();
                    foreach (var item in dictList)
                    {
                        var barcode = item["BarCode"]!.ToString();
                        //根据资产编号查询资产
                        Asset? AssetQuery = YideaClient.GetAsset(barcode!);

                        if (AssetQuery != null)
                        {
                            var obj = JsonSerializer.Deserialize<Dictionary<string, JsonNode>>(AssetQuery.DataJson.ToString());

                            JsonObject SubmitJson = new JsonObject();
                            JsonArray AssetSelet = new JsonArray();
                            JsonObject AssetChild = new JsonObject();
                            SubmitJson.Add(AssetList.FieldId, AssetSelet);
                            AssetSelet.Add(AssetChild);

                            #region 资产列表table
                            AssetChild.Add(BarCode.FieldId, AssetQuery.Barcode);//资产编码
                            AssetChild.Add(FinancialAssetCode.FieldId, item["FinancialCode"]?.ToString());//财务资产编码
                            AssetChild.Add("name", AssetQuery?.Name);//资产名称
                            AssetChild.Add("districtName", AssetQuery?.DistrictName);//区域名称
                            AssetChild.Add("specs", AssetQuery?.Specs);//规格型号
                            AssetChild.Add(JoinName.FieldId, new JsonObject
                            {
                                ["id"] = AssetQuery?.Id,    //资产列表的id
                                [Asset1_FinancialAssetCode.FieldId] = item["FinancialCode"]?.ToString(),//财务资产编码
                                ["name"] = AssetQuery?.Name,//资产名称
                                ["specs"] = AssetQuery?.Specs,//规格型号
                                ["districtName"] = AssetQuery?.DistrictName,//区域名称
                                ["purchasedDate"] = AssetQuery?.PurchasedDate//购入日期

                            });//关联资产数据
                            AssetChild.Add(AssetTypeCode.FieldId, AssetQuery?.AssetTypeCode);//类别编码


                            var codeFirst = AssetQuery?.AssetTypeCode;//编码判断--取首位
                            codeFirst = codeFirst?.Substring(0, 1);
                            AssetChild.Add(TypeCodeIF.FieldId, codeFirst);

                            decimal assetYZ = 0;//资产原值
                            if (obj != null && obj.TryGetValue(Asset1_yuanzhi.FieldId, out var value))
                            {
                                // 尝试将值转换为 decimal
                                if (value != null && decimal.TryParse(value.ToString(), out var parsedValue))
                                {
                                    assetYZ = parsedValue;
                                }
                            }

                            AssetChild.Add(AssetList_yuanzhi.FieldId, assetYZ);

                            decimal ljzj = Convert.ToDecimal(item["LJZJ"].ToString());
                            AssetChild.Add(AssetList_AccumDeper.FieldId, ljzj);//累计折旧
                            decimal assetJZ = 0;
                            if (obj != null && obj.TryGetValue(Asset1_jingzhi.FieldId, out var valueJZ))
                            {
                                // 尝试将值转换为 decimal
                                if (valueJZ != null && decimal.TryParse(valueJZ.ToString(), out var parsedValueJZ))
                                {
                                    assetJZ = parsedValueJZ;
                                }
                            }
                            AssetChild.Add(AssetList_jingzhi.FieldId, assetJZ.ToString());//资产净值
                            AssetChild.Add(AssetList_Number1.FieldId, "");//数字1    备注：暂无可用字段，咨询杨晶
                                                                          //var zjIf = Convert.ToInt32(ljzj) == 0 ? 1 : 0;
                                                                          //AssetChild.Add(AssetList_AccumDeperIF.FieldId, zjIf);//判断累计折旧是不是为0
                            AssetChild.Add(AssetList_CunFangAddress.FieldId, AssetQuery?.Address);//存放地址

                            string cbzxCode = string.Empty;
                            if (obj != null && obj.TryGetValue(Asset1_CBZXcode.FieldId, out var cbzxcodevalue))
                            {
                                cbzxCode = cbzxcodevalue?.ToString() ?? "";
                            }
                            AssetChild.Add(AssetList_CBZX_Code.FieldId, cbzxCode); //成本中心代码
                            string cbzxName = string.Empty;
                            if (obj != null && obj.TryGetValue(Asset1_CBZXname.FieldId, out var cbzxnamevalue))
                            {
                                cbzxName = cbzxnamevalue?.ToString() ?? "";
                            }
                            AssetChild.Add(AssetList_CBZX_Name.FieldId, cbzxName);//成本中心名称


                            //没有写入的字段 暂时不需要
                            //减累计折旧 、加累计折旧、
                            //AssetChild.Add(AssetList_AssetState.FieldId, AssetQuery?.State.ToString());//资产状态
                            //是否递延
                            string sfyd = string.Empty;
                            if (obj != null && obj.TryGetValue(Asset1_WTD.FieldId, out var sfydvalue))
                            {
                                sfyd = sfydvalue?.ToString() ?? "";
                            }

                            AssetChild.Add(AssetList_WTD.FieldId, sfyd);//是否延递
                            string sfgz = string.Empty;
                            if (obj != null && obj.TryGetValue(Asset1_WTP.FieldId, out var sfgzvalue))
                            {
                                sfgz = sfgzvalue?.ToString() ?? "";
                            }
                            AssetChild.Add(AssetList_WTP.FieldId, sfgz);//是否过账
                            AssetChild.Add(Asset1_WTP.FieldId, sfgz);//是否过账
                            AssetChild.Add("id", AssetQuery?.Id);
                            AssetChild.Add("barcode", AssetQuery.Barcode);
                            AssetChild.Add("assetTypeId", AssetQuery.AssetTypeId);
                            AssetChild.Add("amount", AssetQuery.Amount);
                            AssetChild.Add("assetTypeCode", AssetQuery.AssetTypeCode);
                            AssetChild.Add("assetTypeName", AssetQuery.AssetTypeName);
                            AssetChild.Add(Asset1_companyCode.FieldId, item["CompanyCode"]?.ToString());
                            #endregion





                            #region 报废单主表字段
                            //清理人
                            SubmitJson.Add(claerReson.FieldId, new JsonObject
                            {

                                ["value"] = ScrapConstants.ClearReasonEmployeeID,//工号
                                ["label"] = ScrapConstants.ClearReasonFieldName,//清理人姓名
                                ["code"] = ScrapConstants.ClearReasonEmployeeID,
                                ["type"] = "userName"

                            });
                            //清理日期
                            SubmitJson.Add(cleatDate.FieldId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            //工号
                            SubmitJson.Add(staffNo.FieldId, ScrapConstants.ClearReasonEmployeeID);
                            //名字
                            SubmitJson.Add(Name.FieldId, ScrapConstants.ClearReasonFieldName);
                            //资产分类
                            SubmitJson.Add(assetType.FieldId, new JsonArray
                                {
                                    new JsonObject{

                                    ["value"]=AssetQuery?.AssetTypeCode,
                                    ["label"]=AssetQuery?.AssetTypeName
                                    }
                                });
                            //部门选择
                            SubmitJson.Add(department.FieldId, new JsonObject
                            {

                                ["value"] = ScrapConstants.departmentValue,
                                ["code"] = ScrapConstants.departmentCode,
                                ["label"] = ScrapConstants.departmentName,
                                ["type"] = "departmentName"
                            });

                            //公司选择
                            var companyCodeValue = obj?[Asset1_company.FieldId].AsObject();
                            var parr = companyCodeValue.Parent;
                            if (companyCodeValue != null)
                            {
                                // 1. 序列化为 JSON 字符串
                                string jsonStr = companyCodeValue.ToJsonString();

                                // 2. 反序列化为全新的 JsonObject
                                var newObj = JsonNode.Parse(jsonStr).AsObject();

                                // 3. 添加到 SubmitJson
                                SubmitJson.Add(companySelect.FieldId, newObj);
                            }
                            //原值
                            SubmitJson.Add(yuanZhi.FieldId, assetYZ.ToString());
                            //净值
                            SubmitJson.Add(JingZhi.FieldId, assetJZ.ToString());

                            //公司代码
                            SubmitJson.Add(companyCode.FieldId, item["CompanyCode"]?.ToString());
                            //报废类型
                            SubmitJson.Add(ScrapType.FieldId, new JsonObject
                            {
                                ["value"] = "BF04-工程单据作废",
                                ["label"] = "BF04-工程单据作废"
                            });
                            //流程标识
                            SubmitJson.Add(ProcessIdentifier.FieldId, "1");
                            //清理说明
                            SubmitJson.Add(ScraplongText.FieldId, "此报废单为程序自动执行处理结果");
                            #endregion
                            var last = "";
                            var result = JsonSerializer.Serialize(SubmitJson, new JsonSerializerOptions
                            {
                                WriteIndented = true,
                                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                            });

                            UserDefinedForm form = new UserDefinedForm() { FormId = VformId1.Id, JsonData = result };
                            var isResult = YideaClient.AddNewUserDefinedForm(form);
                            if (isResult)
                            {

                                Logger.Info($"长摊资产报废创建成功，资产编码:{barcode},报废单:{form.SerialNo}");
                                obj.Clear();
                                SubmitJson.Clear();
                                AssetSelet.Clear();
                                AssetChild.Clear();
                                conditions.Add($" (Id='{item["Id"].ToString()}' AND BarCode='{barcode}') ");

                            }
                            else
                            {
                                obj.Clear();
                                SubmitJson.Clear();
                                AssetSelet.Clear();
                                AssetChild.Clear();
                                Logger.Info($"长摊资产报废创建失败，资产编码:{barcode},报废单:{form.SerialNo},数据库id：{item["Id"].ToString()}");
                            }



                        }
                        else
                        {
                            Logger.Info($"资产：{item["BarCode"].ToString()}，系统中不存在");
                            throw new Exception($"资产：{item["BarCode"].ToString()}，系统中不存在");
                        }
                    }

                    string Upsql = $"UPDATE SapAssetScrapRequest SET IsTransferred = 1 WHERE {string.Join("OR", conditions)}";
                    Logger.Info($"sql更新语句:  {Upsql}");
                    JsonObject UpSapAssetScrap = new JsonObject()
                    {
                        ["Type"] = "ClearScrapOrderUpdate",
                        ["UpdateSql"] = Upsql
                    };
                    JsonObject? UpCheck = ToClient.SendNotifications(UpSapAssetScrap);
                    if (UpCheck["chechklist"].GetValue<bool>() == false)
                    {
                        Logger.Info($"长摊报废数据库修改失败，SQL语句：【{Upsql}】");
                    }
                    else
                    {
                        Logger.Info($"长摊报废数据库修改成功，SQL语句：【{Upsql}】");
                    }

                }
                else
                {
                    Logger.Info("报废资产暂无数据，我们下次见........");
                }
            }
            catch (SqlException sqlEx)
            {
                Logger.Error($"SQL 异常: {sqlEx.Message}, 错误码: {sqlEx.Number}");
                throw new Exception("数据库操作异常，请检查", sqlEx);
            }
            catch (Exception ex)
            {

                throw new Exception("处理报废资产数据库修改时发生异常", ex);
            }
          

        }
        // 定义常量类
        public static class ScrapConstants
        {
            /// <summary>
            /// 查询sql
            /// </summary>
            public const string SelectSqlTemplate = "SELECT * FROM SapAssetScrapRequest WHERE IsTransferred=false ORDER BY CreateTime ASC LIMIT 30";

            /// <summary>
            /// 清理人
            /// </summary>
            public const string ClearReasonFieldName = "simon.li 李伟";

            /// <summary>
            /// 工号
            /// </summary>
            public const string ClearReasonEmployeeID = "202106485";

            /// <summary>
            /// 部门Id
            /// </summary>
            public const int departmentValue = 1176302;

            /// <summary>
            /// 部门代码
            /// </summary>
            public const string departmentCode = "1040512";

            /// <summary>
            /// 部门名称
            /// </summary>
            public const string departmentName = "总部";


            // ... 其他常量
        }


    }
}
